﻿
#include <windows.h>
#include <tchar.h>

#include "video.h"
#include "font.h"
#include "stream.h"
#include "streaminfo.h"
#include "util.h"


//////////////////////////////////////////////////////////////////////////

CStream	stream;
CVideo	video;
CFont	font;

void HotKey_Quit(void)
{
	SDL_Event event;
	event.type = SDL_USEREVENT;
	SDL_PushEvent(&event);
}


int SDLCALL FilterEvents(const SDL_Event *event)
{
	static int reallyquit = 0;
	static bool lpush = false;

	switch (event->type) 
	{
		case SDL_SYSWMEVENT :
			{
				SDL_SysWMEvent sysevent;
				sysevent = event->syswm;
				switch( sysevent.msg->msg )
				{
					case WM_DROPFILES :
					{
						wchar_t    filename[256];
						DragQueryFileW((HDROP) sysevent.msg->wParam, 0, filename, _countof(filename));

						_TRACE(_T("%s\n"),filename);
					}
					break;
				}
			}
			return 0;


		case SDL_MOUSEBUTTONDOWN:
		case SDL_MOUSEBUTTONUP:
			if ( event->button.state == SDL_PRESSED ) 
			{
				if( event->button.button == SDL_BUTTON_LEFT )
				{
					lpush = true;

					POINT	pos;
					RECT	rect;

					::GetCursorPos(&pos);
					::GetWindowRect(video.GetWindowHandle(), &rect);

					video.SetCursorPos(pos);
					video.SetWindowRect(rect);

				}
			}
			else if ( event->button.state == SDL_RELEASED ) 
			{
				if( event->button.button == SDL_BUTTON_LEFT )
					lpush = false;
			}
			return(0);

		case SDL_MOUSEMOTION:
			if( lpush )
			{
				POINT tmp;

				::GetCursorPos(&tmp);
				::MoveWindow(video.GetWindowHandle(),
					video.GetWindowRect().left - video.GetCursorPos().x + tmp.x,
					video.GetWindowRect().top  - video.GetCursorPos().y + tmp.y,
					video.GetWindowRect().right - video.GetWindowRect().left,
					video.GetWindowRect().bottom - video.GetWindowRect().top, TRUE);
			}
			return(0);

		case SDL_KEYDOWN:
 			if ( event->key.keysym.sym == SDLK_ESCAPE || 
			((event->key.keysym.sym == SDLK_F4) && (event->key.keysym.mod & KMOD_ALT)) )
			{
 				//HotKey_Quit();
				SDL_Event event;
				event.type = SDL_USEREVENT;
				SDL_PushEvent(&event);

 			}
// 			if ( (event->key.keysym.sym == SDLK_g) &&
// 			     (event->key.keysym.mod & KMOD_CTRL) ) {
// 				HotKey_ToggleGrab();
// 			}
// 			if ( (event->key.keysym.sym == SDLK_z) &&
// 			     (event->key.keysym.mod & KMOD_CTRL) ) {
// 				HotKey_Iconify();
// 			}
// 			if ( (event->key.keysym.sym == SDLK_RETURN) &&
// 			     (event->key.keysym.mod & KMOD_ALT) ) {
// 				HotKey_ToggleFullScreen();
// 			}
			return(0);

		case SDL_KEYUP:
//			PrintKey(&event->key.keysym, 0);
			return(0);

		/* Pass the video resize event through .. */
		case SDL_VIDEORESIZE:
			return(1);

// 		/* This is important!  Queue it if we want to quit. */
		case SDL_QUIT:
			if ( ! reallyquit ) {
				reallyquit = 1;
				printf("Quit requested\n");
				return(0);
			}
			printf("Quit demanded\n");
			return(1);

		/* This will never happen because events queued directly
		   to the event queue are not filtered.
		 */
		case SDL_USEREVENT:
			return(1);

		/* Drop all other events */
		default:
			return(0);
	}
}

bool decode = false;

void MainLoop()
{
	if( decode == false )
	{
		video.LockOverlay();
		stream.RenderFrameToOverlay( video.GetOverlay() );

		video.Render(10, 10, font.GetSurface());

		video.UnLockOverlay();
		video.RenderOverlay( stream.m_streamWidth, stream.m_streamHeight );

		decode = true;
	}
	else
		Sleep(10);
}

#define REFRESH_EVENT (SDL_USEREVENT + 1)

//static Uint32 SDLCALL ticktock(Uint32 interval)
static Uint32 ticktock(Uint32 interval, void *opaque) 
{
	//MainLoop();
	//video.RenderOverlay( stream.m_streamWidth, stream.m_streamHeight );
	decode = false;

	//video.Render(10, 10, font.GetSurface());
	//video.Present();

	SDL_Event event;
	event.type = REFRESH_EVENT;
	event.user.data1 = opaque;
	SDL_PushEvent(&event);

	return(interval);
}

//////////////////////////////////////////////////////////////////////////

// SDL 플레이 콜백
void audio_callback(void *userdata, Uint8 *str, int len) 
{
	AVCodecContext *aCodecCtx = stream.GetAudio();

	int len1, audio_size;

	static uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
	static unsigned int audio_buf_size = 0;
	static unsigned int audio_buf_index = 0;

	while(len > 0) 
	{
		if(audio_buf_index >= audio_buf_size) 
		{
			/* We have already sent all our data; get more */

			//audio_size = audio_decode_frame(aCodecCtx, audio_buf, sizeof(audio_buf));

			audio_size = stream.DecodeAudio(audio_buf, sizeof(audio_buf));

			if(audio_size < 0) 
			{
				/* If error, output silence */
				audio_buf_size = 1024; // arbitrary?
				memset(audio_buf, 0, audio_buf_size);
			} 
			else 
			{
				audio_buf_size = audio_size;
			}
			audio_buf_index = 0;
		}

		len1 = audio_buf_size - audio_buf_index;
		if(len1 > len)
			len1 = len;
		memcpy(str, (uint8_t *)audio_buf + audio_buf_index, len1);
		len -= len1;
		str += len1;
		audio_buf_index += len1;
	}

}

bool SetUpAudio()
{
	SDL_AudioSpec   wanted_spec, spec;
	wanted_spec.freq = stream.m_audioFreq;
	wanted_spec.format = AUDIO_S16SYS;
	wanted_spec.channels = stream.m_audioChannels;
	wanted_spec.silence = 0;
	wanted_spec.samples = stream.m_audioSamples;
	wanted_spec.callback = audio_callback;
	wanted_spec.userdata = NULL;

	if(SDL_OpenAudio(&wanted_spec, &spec) < 0) 
		return false;
	SDL_PauseAudio(0);

	return true;
}

int WINAPI WinMain(HINSTANCE Instance, HINSTANCE, LPSTR, INT)
{
	int kk = 0;

	SDL_Event event;
	video.InitVideo(400, 300);
	stream.Open("test.avi");

	font.Render(_T("English にほんご 한국어"));
	//video.Render(10, 10, font.GetSurface());
	//video.Present();
	video.InitOverlay(stream.m_streamWidth, stream.m_streamHeight, stream.m_streamFormat);

	SDL_SetEventFilter(FilterEvents);
	SDL_AddTimer(40, ticktock, NULL);

	SetUpAudio();
	

/*
	while ( SDL_WaitEvent(&event)) 
	{
		switch (event.type) 
		{
			case SDL_VIDEORESIZE:
				printf("Got a resize event: %dx%d\n",event.resize.w, event.resize.h);
//				SetVideoMode(event.resize.w, event.resize.h);
				break;
			case SDL_USEREVENT:
				printf("Handling internal quit request\n");
				/ * Fall through to the quit handler * /
			case SDL_QUIT:
				//printf("Bye bye..\n");
				return 0;
				break;

			default:
				/ * This should never happen * /
				printf("Warning: Event %d wasn't filtered\n",
					event.type);
				break;
		}

		MainLoop();
	}
*/



	bool quit = false;
    while( quit == false )
    {
		while( SDL_PollEvent( &event ) )
		{
			if( event.type == SDL_QUIT )
			{
				quit = true;
			}

		if( event.type == REFRESH_EVENT )
			//video_refresh_timer(event.user.data1);
			MainLoop();
			break;

		}

		//MainLoop();
    }

	return 0;
}

